package com.budwk.app.sqfwV2.generator.dayingRoadExcel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.component.SignImageComponent;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.image.FireSafetyOnDayingRoadExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 8 小型生产场所台账/Excel
 */

@Slf4j
public class SmallBusinessPremisesBookGenerator extends BaseTemplateExcelGenerator implements DayingRoadExcelGenerator {

    @Override
    protected String getTemplateName() {
        return DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_SCALE.getFilePath();
    }

    /**
    * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
    *
    * @return 文件名名称
    */
    @Override
    public String getDownloadFileName() {
        //TODO 在这里返回你生成的文件名名称，注意注意注意不用带上后缀
        return DayingRoadPdfComponent.getDictName(DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_SCALE.getCode(), null);
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("SmallBusinessPremisesBookGenerator getBaseExcelParamDTO: {}", JSONObject.toJSONString(excelCreateParam.getBaseExcelParamDTO()));
        excelParam.put("area", excelCreateParam.getBaseExcelParamDTO().getDistrict());
        excelParam.put("street", excelCreateParam.getBaseExcelParamDTO().getCounty());
        excelParam.put("downloadYear", DateUtil.year(new Date()));
        excelParam.put("downloadMonth", DateUtil.month(new Date()) + 1);
        excelParam.put("downloadDay", DateUtil.dayOfMonth(new Date()));
    }

    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        List<Sqfw_formSummary_new> summaryList = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        SysDictService dictService = NutzIocUtils.getBean(SysDictService.class);
        log.info("SmallBusinessPremisesBookGenerator customerDataParam summaryList: {}", JSONObject.toJSONString(summaryList));
        int num = 1;
        SysUserService userService = NutzIocUtils.getBean(SysUserService.class);
        Set<String> userIdSet = summaryList.stream().map(Sqfw_formSummary_new::getCreateBy).collect(Collectors.toSet());
        List<Sys_user> users = userService.getUserByIds(userIdSet);
        for (Sqfw_formSummary_new summary : summaryList) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            log.info("SmallBusinessPremisesBookGenerator customerDataParam roadPdfDTO: {}", JSONObject.toJSONString(roadPdfDTO));
            if (!isGenerateExcel(roadPdfDTO)) {
                continue;
            }
            // 构建数据
            Map<String, Object> map = buildExcelMap(roadPdfDTO, summary, dictService);
            map.put("num", num ++);
            Optional<Sys_user> optional = users.stream().filter(e -> e.getId().equals(summary.getCreateBy())).findFirst();
            if (optional.isPresent()) {
                Sys_user sysUser = optional.get();
                SignImageComponent.signExcel(map, 1, sysUser.getSignatureUrl(), "", "checkedUnitLeader", "checkedUnitLeaderStr");
            } else {
                SignImageComponent.signExcel(map, 1, null, summary.getCreateUserName(), "checkedUnitLeader", "checkedUnitLeaderStr");
            }
            listMap.add(map);
        }
        log.info("SmallBusinessPremisesBookGenerator customerDataParam end: {}", JSONObject.toJSONString(listMap));
    }

    private Map<String, Object> buildExcelMap(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, Sqfw_formSummary_new summary, SysDictService dictService) {
        Map<String, Object> map = new HashMap<>();
        map.put("placeName", StrUtil.replaceNullStr(roadPdfDTO.getPlaceName()));
        map.put("socialCreditCode", StrUtil.replaceNullStr(roadPdfDTO.getSocialCreditCode()));
        // 所属区(市、县)
        map.put("cityArea", String.format("%s%s", StrUtil.formatStr(summary.getCity()), StrUtil.formatStr(summary.getDistrict())));
        // 乡镇(街道)、村(社区)
        String street = StrUtil.formatStr(summary.getCounty());
        String community = StrUtil.formatStr(summary.getCommunity());
        String streetCommunity = street + "、" + community;
        if (StringUtils.isBlank(street) && StringUtils.isBlank(community)) streetCommunity = "--";
        map.put("streetCommunity", streetCommunity);

        map.put("address", StrUtil.replaceNullStr(roadPdfDTO.getAddress()));
        // 行业分类(从下拉菜单选择)
        List<String> names = DayingRoadPdfComponent.getIndustrySectorStr(roadPdfDTO.getIndustrySector());
        map.put("industySector", names.size() > 0 ? String.join("、", names) : CommonConstants.HORIAONTAL_LINE);
        // staffNumber 从业人数
        map.put("staffNumber", CommonConstants.HORIAONTAL_LINE);
        if (StringUtils.isNotEmpty(roadPdfDTO.getStaffNumber())) {
            Sys_dict sysDict = dictService.fetch(Cnd.where(Sys_dict::getCode, "=", roadPdfDTO.getStaffNumber()));
            map.put("staffNumber", sysDict != null ? sysDict.getName() : CommonConstants.HORIAONTAL_LINE);
        }
        map.put("operator", StrUtil.replaceNullStr(roadPdfDTO.getOperator()));
        map.put("operatorTelephone", StrUtil.replaceNullStr(roadPdfDTO.getOperatorTelephone()));

        // 经营范围/主要产品
        String mainProducts = roadPdfDTO.getMainProducts();
        String mainBusinessScope = roadPdfDTO.getMainBusinessScope();
        if (StringUtils.isNotEmpty(mainBusinessScope)) {
            Sys_dict sysDict = dictService.fetch(Cnd.where(Sys_dict::getCode, "=", mainBusinessScope));
            mainBusinessScope = sysDict != null ? sysDict.getName() : "";
        }
        if (StringUtils.isBlank(mainBusinessScope)) mainBusinessScope = "-";
        if (StringUtils.isBlank(mainProducts)) mainProducts = "-";
        map.put("a5A52", mainBusinessScope + "/" + mainProducts);
        // 存在主要风险
        map.put("mainRisk", getMainRisk(roadPdfDTO.getFireAndElectricityUsage()));
        map.put("remark", "");

        map.put("fillDate", DateUtil.format(summary.getFillDate(), DatePattern.NORM_DATE_PATTERN));

        List<byte[]> picture = CommonFormOfficeUtils.addPictureToByteList(roadPdfDTO.getVisitPictures(), 1);
        map.put("visitPictures", null);
        map.put("visitPicturesStr", null);
        if (picture.size() > 0) {
            map.put("visitPictures", picture);
        } else {
            map.put("visitPicturesStr", CommonConstants.HORIAONTAL_LINE);
        }
        // 居委会负责人
        map.put("committeePerson", StrUtil.replaceNullStr(summary.getCreateUserName()));
        return map;
    }

    private String getMainRisk(String fireAndElectricityUsage) {
        List<String> mainRiskList = Lists.newArrayList();
        if (StringUtils.isBlank(fireAndElectricityUsage)) fireAndElectricityUsage = "";
        Set<String> fireUsageSet = Sets.newHashSet(Splitter.on(",").split(fireAndElectricityUsage));
        if (fireUsageSet.contains(DictConstants.BOTTLED_GAS) || fireUsageSet.contains(DictConstants.NATURAL_GAS) || fireUsageSet.contains(DictConstants.BOTTLED_ETHER)) {
            mainRiskList.add("气瓶使用");
        }
        if (fireUsageSet.contains(DictConstants.BOTTLED_GAS_FUELS)) {
            mainRiskList.add("火灾");
        }
        if (fireUsageSet.contains(DictConstants.BOTTLED_ETHER_ELECTRICITY)) {
            mainRiskList.add("电气伤害");
        }
        if (fireUsageSet.contains(DictConstants.BOTTLED_ETHER_CHARCOAL)) {
            mainRiskList.add("使用炭火");
        }
        if (mainRiskList.size() > 0) {
            return Joiner.on("/").join(mainRiskList);
        }
        return CommonConstants.HORIAONTAL_LINE;
    }

    /**
     * ○有数据就生成表格。
     * @param roadPdfDTO
     * @return
     */
    public boolean isGenerateExcel(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        // 判断a5是否为重点场所 选择重点场所 不生成表格
        return !DayingRoadPdfComponent.isKeyLocations(roadPdfDTO);
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    /**
     * 如果在遍历之前就能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelCreateParam excel生成所需的最为全面的数据
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return DayingRoadPdfComponent.getSqfwExcelJudgeRes(excelCreateParam, new SmallBusinessPremisesBookGenerator());
    }

    /**
     * 如果在遍历之后能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected Class<?> getImageConfigBO() {
        return FireSafetyOnDayingRoadExcelImageConfigBO.class;
    }
}
